package com.lz.service.impl;

import com.lz.convertor.OrderMaster2OrderMasterQueryConvertor;
import com.lz.dao.OrderDetailDao;
import com.lz.dao.OrderMasterDao;
import com.lz.entity.*;
import com.lz.enums.OrderStatusEnum;
import com.lz.enums.PayStatusEnum;
import com.lz.enums.ResultEnum;
import com.lz.exception.SellException;
import com.lz.service.OrderService;
import com.lz.service.PayService;
import com.lz.service.ProductInfoService;
import com.lz.utils.KeyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单实现类
 * Created by lz on 2018/8/17.
 */
@Service
@Slf4j
public class OrderServiceImpl implements OrderService{

    @Autowired
    private ProductInfoService productInfoService;

    @Autowired
    private OrderDetailDao orderDetailDao;

    @Autowired
    private OrderMasterDao orderMasterDao;

    @Autowired
    private PayService payService;

    /**
     * 创建订单
     * @param orderMasterQuery
     * @return
     */
    @Override
    @Transactional
    public OrderMasterQuery createOrder(OrderMasterQuery orderMasterQuery) {
        //获取订单id
        String orderId = KeyUtil.genUniqueKey();
        //总价初始化
        BigDecimal orderAmount = new BigDecimal(BigInteger.ZERO);
        //购物车类
//        List<CartQuery> cartQueryList = new ArrayList<>();

        // 1. 查询商品（数量，价格）
        for (OrderDetail orderDetail : orderMasterQuery.getOrderDetailList()){
            ProductInfo productInfo = productInfoService.findOne(orderDetail.getProductId());
            if (productInfo == null){
                throw new SellException(ResultEnum.PRODUCT_NOT_EXIST);
            }
            // 2. 计算订单总价()
            orderAmount = productInfo.getProductPrice()
                    .multiply(new BigDecimal(orderDetail.getProductCount())).add(orderAmount);

            //订单详情入库
            orderDetail.setOrderId(orderId);
            orderDetail.setDetailId(KeyUtil.genUniqueKey());
            BeanUtils.copyProperties(productInfo,orderDetail);
            orderDetailDao.save(orderDetail);
            //扣去库存
//            CartQuery cartQuery = new CartQuery(orderDetail.getProductId(),orderDetail.getProductCount());
//            cartQueryList.add(cartQuery);
        }

        // 3. 写入数据库（两张表）
        OrderMaster orderMaster = new OrderMaster();
        orderMasterQuery.setOrderId(orderId);
        orderMasterQuery.setOrderAmount(orderAmount);
        BeanUtils.copyProperties(orderMasterQuery,orderMaster);
        orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());
        orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());
        orderMasterDao.save(orderMaster);

        // 4. 扣库存
        List<CartQuery> cartQueryList = orderMasterQuery.getOrderDetailList().stream().map(e ->
                new CartQuery(e.getProductId(),e.getProductCount())
        ).collect(Collectors.toList());
        productInfoService.decreaseStock(cartQueryList);

        return orderMasterQuery;
    }

    /**
     * 查询订单
     * @param orderId
     * @return
     */
    @Override
    public OrderMasterQuery findOne(String orderId) {
        OrderMaster orderMaster = orderMasterDao.findOne(orderId);
        if (orderMaster == null){
            throw new SellException(ResultEnum.ORDER_NOT_EXIST);
        }
        List<OrderDetail> orderDetails = orderDetailDao.findByOrderId(orderId);
        if (CollectionUtils.isEmpty(orderDetails)){
            throw new SellException(ResultEnum.DETAIL_NOT_EXIST);
        }

        OrderMasterQuery orderMasterQuery = new OrderMasterQuery();
        BeanUtils.copyProperties(orderMaster,orderMasterQuery);
        orderMasterQuery.setOrderDetailList(orderDetails);

        return orderMasterQuery;
    }

    /**
     * 查询所有订单
     * @param openid
     * @param pageable
     * @return
     */
    @Override
    public Page<OrderMasterQuery> findList(String openid, Pageable pageable) {
        Page<OrderMaster> byBuyerOpenid = orderMasterDao.findByBuyerOpenid(openid, pageable);
        List<OrderMasterQuery> convert = OrderMaster2OrderMasterQueryConvertor.convert(byBuyerOpenid.getContent());
        return new PageImpl<OrderMasterQuery>(convert,pageable,byBuyerOpenid.getTotalElements());
    }

    /**
     * 取消订单
     * @param orderMasterQuery
     * @return
     */
    @Override
    @Transactional
    public OrderMasterQuery cancelOrder(OrderMasterQuery orderMasterQuery) {
        OrderMaster orderMaster = new OrderMaster();
        //判断订单状态
        if (!orderMasterQuery.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())){
            log.error("【取消订单】订单状态不正确,orderId={},orderStatus={}",
                    orderMasterQuery.getOrderId(),orderMasterQuery.getOrderStatus());
            throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
        }
        //修改订单状态
        orderMasterQuery.setOrderStatus(OrderStatusEnum.CANCEL.getCode());
        BeanUtils.copyProperties(orderMasterQuery,orderMaster);
        OrderMaster save = orderMasterDao.save(orderMaster);
        if (save == null){
            log.error("【取消订单】更新失败，orderMaster={}",orderMaster);
            throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);
        }

        //返回库存
        if (CollectionUtils.isEmpty(orderMasterQuery.getOrderDetailList())){
            log.error("【取消订单】订单中无商品详情，orderMasterQuery={}",orderMasterQuery);
            throw new SellException(ResultEnum.ORDER_DETAIL_EMPTY);
        }
        List<CartQuery> cartQueryList = orderMasterQuery.getOrderDetailList().stream()
                .map(e -> new CartQuery(e.getProductId(),e.getProductCount()))
                .collect(Collectors.toList());
        productInfoService.increaseStock(cartQueryList);

        //如果支付了，需要退款
        if (orderMasterQuery.getPayStatus().equals(PayStatusEnum.SUCCESS.getCode())){
            payService.refund(orderMasterQuery);
        }

        return orderMasterQuery;
    }

    /**
     * 订单完结
     * @param orderMasterQuery
     * @return
     */
    @Override
    @Transactional
    public OrderMasterQuery finishOrder(OrderMasterQuery orderMasterQuery) {
        //判断订单状态
        if (!orderMasterQuery.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())){
            log.error("【完结订单】订单状态不正确，orderId={},orderStatus={}",orderMasterQuery.getOrderId(),orderMasterQuery.getOrderStatus());
            throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
        }
        //修改订单状态
        orderMasterQuery.setOrderStatus(OrderStatusEnum.FINISHED.getCode());
        OrderMaster orderMaster = new OrderMaster();
        BeanUtils.copyProperties(orderMasterQuery,orderMaster);
        OrderMaster save = orderMasterDao.save(orderMaster);
        if (save == null){
            log.error("【完结订单】更新失败，orderMaster={}",orderMaster);
            throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);
        }
        return orderMasterQuery;
    }

    @Override
    @Transactional
    public OrderMasterQuery paidOrder(OrderMasterQuery orderMasterQuery) {
        //判断订单状态
        if (!orderMasterQuery.getOrderStatus().equals(OrderStatusEnum.NEW.getCode())){
            log.error("【订单支付】订单状态不正确，orderId={},orderStatus={}",orderMasterQuery.getOrderId(),orderMasterQuery.getOrderStatus());
            throw new SellException(ResultEnum.ORDER_STATUS_ERROR);
        }

        //判断支付状态
        if (!orderMasterQuery.getPayStatus().equals(PayStatusEnum.WAIT.getCode())){
            log.error("【订单支付】订单支付状态不正确，orderMasterQuery={}",orderMasterQuery);
            throw new SellException(ResultEnum.ORDER_PAY_STATUS_ERROR);
        }

        //修改订单支付状态
        orderMasterQuery.setPayStatus(PayStatusEnum.SUCCESS.getCode());
        OrderMaster orderMaster = new OrderMaster();
        BeanUtils.copyProperties(orderMasterQuery,orderMaster);
        OrderMaster save = orderMasterDao.save(orderMaster);
        if (save == null){
            log.error("【订单支付】更新失败，orderMaster={}",orderMaster);
            throw new SellException(ResultEnum.ORDER_UPDATE_FAIL);
        }

        return orderMasterQuery;
    }

    /**
     * 查询订单列表
     * @param pageable
     * @return
     */
    @Override
    public Page<OrderMasterQuery> findList(Pageable pageable) {
        Page<OrderMaster> all = orderMasterDao.findAll(pageable);
        List<OrderMasterQuery> convert = OrderMaster2OrderMasterQueryConvertor.convert(all.getContent());

        return new PageImpl<>(convert,pageable,all.getTotalElements());
    }
}
